home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: ocomp.r
- * Contents: lexeq, lexge, lexgt, lexle, lexlt, lexne, numeq, numge,
- * numgt, numle, numlt, numne, eqv, neqv
- */
-
- /*
- * NumComp is a macro that defines the form of a numeric comparisons.
- */
- #begdef NumComp(icon_op, func_name, c_op, descript)
- "x " #icon_op " y - test if x is numerically " #descript " y."
- operator{0,1} icon_op func_name(x,y)
- #ifdef LargeInts
- declare {
- tended struct descrip lx, ly;
- }
- #endif /* LargeInts */
- if cnv:(exact)C_integer(x) && cnv:(exact)C_integer(y) then {
- abstract {
- return integer
- }
- inline {
- if c_op(x, y)
- return C_integer y;
- fail;
- }
- }
- #ifdef LargeInts
- else if cnv:(exact)integer(x,lx) && cnv:(exact)integer(y,ly) then {
- abstract {
- return integer
- }
- inline {
- if (big_ ## c_op (lx,ly)) {
- return ly;
- }
- fail;
- }
- }
- #endif /* LargeInts */
- else {
- if !cnv:C_double(x) then
- runerr(102,x)
- if !cnv:C_double(y) then
- runerr(102,y)
- abstract {
- return real
- }
- inline {
- if c_op (x, y)
- return C_double y;
- fail;
- }
- }
- end
-
- #enddef
-
- /*
- * x = y
- */
- #define NumEq(x,y) (x == y)
- #define big_NumEq(x,y) (bigcmp(&x,&y) == 0)
- NumComp( = , numeq, NumEq, equal to)
-
- /*
- * x >= y
- */
- #define NumGe(x,y) (x >= y)
- #define big_NumGe(x,y) (bigcmp(&x,&y) >= 0)
- NumComp( >=, numge, NumGe, greater than or equal to)
-
- /*
- * x > y
- */
- #define NumGt(x,y) (x > y)
- #define big_NumGt(x,y) (bigcmp(&x,&y) > 0)
- NumComp( > , numgt, NumGt, greater than)
-
- /*
- * x <= y
- */
- #define NumLe(x,y) (x <= y)
- #define big_NumLe(x,y) (bigcmp(&x,&y) <= 0)
- NumComp( <=, numle, NumLe, less than or equal to)
-
- /*
- * x < y
- */
- #define NumLt(x,y) (x < y)
- #define big_NumLt(x,y) (bigcmp(&x,&y) < 0)
- NumComp( < , numlt, NumLt, less than)
-
- /*
- * x ~= y
- */
- #define NumNe(x,y) (x != y)
- #define big_NumNe(x,y) (bigcmp(&x,&y) != 0)
- NumComp( ~=, numne, NumNe, not equal to)
-
- /*
- * StrComp is a macro that defines the form of a string comparisons.
- */
- #begdef StrComp(icon_op, func_name, special_test, c_comp, comp_value, descript)
- "x " #icon_op " y - test if x is lexically " #descript " y."
- operator{0,1} icon_op func_name(x,y)
- declare {
- int temp_str = 0;
- }
- abstract {
- return string
- }
- if !cnv:tmp_string(x) then
- runerr(103,x)
- if !is:string(y) then
- if cnv:tmp_string(y) then
- inline {
- temp_str = 1;
- }
- else
- runerr(103,y)
-
- body {
-
- /*
- * lexcmp does the work.
- */
- if (special_test (lexcmp(&x, &y) c_comp comp_value)) {
- /*
- * Return y as the result of the comparison. If y was converted to
- * a string, a copy of it is allocated.
- */
- result = y;
- if (temp_str)
- Protect(StrLoc(result) = alcstr(StrLoc(result), StrLen(result)), runerr(0));
- return result;
- }
- else
- fail;
- }
- end
- #enddef
-
- StrComp(==, lexeq, (StrLen(x) == StrLen(y)) &&, ==, Equal, equal to)
- StrComp(~==, lexne, (StrLen(x) != StrLen(y)) ||, !=, Equal, not equal to)
-
- StrComp(>>=, lexge, , !=, Less, greater than or equal to)
- StrComp(>>, lexgt, , ==, Greater, greater than)
- StrComp(<<=, lexle, , !=, Greater, less than or equal to)
- StrComp(<<, lexlt, , ==, Less, less than)
-
-
- "x === y - test equivalence of x and y."
-
- operator{0,1} === eqv(x,y)
- abstract {
- return type(y)
- }
- inline {
- /*
- * Let equiv do all the work, failing if equiv indicates non-equivalence.
- */
- if (equiv(&x, &y))
- return y;
- else
- fail;
- }
- end
-
-
- "x ~=== y - test inequivalence of x and y."
-
- operator{0,1} ~=== neqv(x,y)
- abstract {
- return type(y)
- }
- inline {
- /*
- * equiv does all the work.
- */
- if (!equiv(&x, &y))
- return y;
- else
- fail;
- }
- end
-